﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Diagnostics;

namespace Updater
{
    using Common;

    public partial class formUpdater : Form
    {
        private static SettingsManager updater_settings_ = new SettingsManager();

        private static readonly string PARAMDOWNLOADURL = "download_url";
        private static readonly string PARAMDEFAULTDELAY = "default_delay";
        private string downloaded_file_ = string.Empty;
        private int default_delay_ = 7;
        private string default_download_url_ = "http://dl.dropbox.com/u/31619017/Updater/Updater.xml";
        private string software_ = string.Empty;
        private string architecture_ = string.Empty;
        private string current_version_ = string.Empty;
        private string last_download_ = string.Empty;
        private string sofware_key_ = string.Empty;

        public formUpdater(string software, string architecture, string current_version)
        {
            InitializeComponent();

            this.Text = string.Format(this.Text, string.Format("{0} - {1}", software, architecture));
            lblMessage.Text = string.Format(lblMessage.Text, software);

            software_ = software;
            architecture_ = architecture;
            current_version_ = current_version;

            sofware_key_ = string.Format("{0}-{1}", software_, architecture_);
        }

        public void LoadSettings()
        {
            if (updater_settings_.SettingsExists(true, "Updater"))
                updater_settings_.LoadSettings(true, "Updater", true);
            else if (updater_settings_.SettingsExists(false, "Updater"))
                updater_settings_.LoadSettings(false, "Updater", true);

            if (!updater_settings_.Keys.Contains(PARAMDOWNLOADURL))
                updater_settings_.Add(PARAMDOWNLOADURL, default_download_url_);

            if (!updater_settings_.Keys.Contains(PARAMDEFAULTDELAY))
            {
                updater_settings_.Add(PARAMDEFAULTDELAY);
                updater_settings_[PARAMDEFAULTDELAY] = default_delay_.ToString();
            }
        }

        private bool CheckIfNeeded()
        {
            string last_check = updater_settings_[sofware_key_];

            if (!string.IsNullOrEmpty(last_check))
            {
                DateTime last = DateTime.Parse(last_check);

                TimeSpan delta = (DateTime.Now - last);

                if (delta.TotalDays < int.Parse(updater_settings_[PARAMDEFAULTDELAY]))
                {
                    return false;
                }
            }

            return true;
        }

        private bool DownloadUpdaterFile()
        {
            WebClient wc = new WebClient();
            downloaded_file_ = Path.GetTempFileName();

            try
            {
                wc.DownloadFile(updater_settings_[PARAMDOWNLOADURL], downloaded_file_);
            }
            catch
            {
                return false;
            }

            return true;
        }

        private bool CheckForUpdate()
        {
            SettingsManager sm = new SettingsManager();
            sm = sm.Deserialize(downloaded_file_);

            string last_version = sm[string.Format("{0}-{1}", software_, architecture_)];
            last_download_ = sm[string.Format("{0}-{1}-Download", software_, architecture_)];

            if (string.IsNullOrEmpty(last_version) || string.IsNullOrEmpty(last_download_))
            {
                return false;
            }

            lblAvailableVersion.Text = last_version;
            lblYourVersion.Text = current_version_;

            return true;
        }

        private bool CheckVersion()
        {
            string[] current = current_version_.Split('.');
            string[] last = lblAvailableVersion.Text.Split('.');

            int count = Math.Min(current.Length, last.Length);
            bool new_version = false;
            bool all_equal = true;

            for (int i = 0; i < count; ++i)
            {
                int c = int.Parse(current[i]);
                int l = int.Parse(last[i]);

                if (c < l)
                {
                    new_version = true;
                    all_equal = false;
                    break;
                }
                if (c > l)
                {
                    all_equal = false;
                    break;
                }
            }

            if (all_equal && last.Length > current.Length)
                new_version = true;

            return new_version;
        }

        private void formUpdater_Load(object sender, EventArgs e)
        {
            LoadSettings();

            if (!CheckIfNeeded() ||
                !DownloadUpdaterFile() ||
                !CheckForUpdate() ||
                !CheckVersion())
            {
                this.DialogResult = System.Windows.Forms.DialogResult.Abort;
                this.Close();
                return;
            }

            SaveSettings();
        }

        private void linkDownload_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Process.Start(last_download_);
            this.Close();
        }

        private void formUpdater_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.DialogResult == System.Windows.Forms.DialogResult.None)
            {
                this.DialogResult = System.Windows.Forms.DialogResult.OK;
            }
        }

        private void SaveSettings()
        {
            updater_settings_.Add(sofware_key_);
            updater_settings_[sofware_key_] = DateTime.Now.ToString();

            try
            {
                updater_settings_.SaveSettings(true, "Updater");
            }
            catch
            {
                updater_settings_.SaveSettings(false, "Updater");
            }
        }
    }
}
